package hit.core;


import java.util.Calendar;
import java.util.Date;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

public class ItemTest {
	Item item;
	
	@Before
	public void SetUp() throws Exception {
		item = new Item();
	}

	@After
	public void TearDown() throws Exception {
		item = null;
	}
	
	@Test
	public void TestIsRemoved() {
		assertFalse(item.IsRemoved());
		
		item.Remove();
		assertTrue(item.IsRemoved());
	}
	
	@Test(expected=IllegalStateException.class)
	public void TestDoubleRemove() {
		item.Remove();
		item.Remove();
	}
	
	@Test
	public void TestGetAndSetProduct() {
		Product product1 = new Product();
		Product product2 = new Product();
		
		item.SetProduct(product1);
		assertEquals(item.GetProduct(), product1);
		
		item.SetProduct(product2);
		assertEquals(item.GetProduct(), product2);
	}
	
	@Test(expected=IllegalArgumentException.class)
	public void TestInvalidBarcode() {
		item.SetBarcode(new Barcode (""));
	}
	
	@Test
	public void TestGetAndSetEntry() {
		Date date1 = new Date();
		item.SetEntry(date1);
		assertEquals(item.GetEntry(), date1);
		
		Date date2 = new Date();
		item.SetEntry(date2);
		assertEquals(item.GetEntry(), date2);
	}
	
	@Test(expected=IllegalArgumentException.class) 
	public void TestInvalidEntry() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE) + 1);
		
		item.SetEntry(cal.getTime());
	}
	
	@Test
	public void TestGetAndSetExit() {
		Date date1 = new Date();
		item.SetExit(date1);
		assertEquals(item.GetExit(), date1);
		
		Date date2 = new Date();
		item.SetExit(date2);
		assertEquals(item.GetExit(), date2);
	}

	@Test(expected=IllegalArgumentException.class) 
	public void TestInvalidExit() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE) + 1);
		
		item.SetExit(cal.getTime());
	}
	
	@Test 
	public void TestGetAndSetProductContainer() {
		ProductContainer container1 = new ProductGroup("Explosives");
		item.SetContainer(container1);
		assertEquals(item.GetContainer(), container1);
		
		ProductContainer container2 = new StorageUnit("Armory");
		item.SetContainer(container2);
		assertEquals(item.GetContainer(), container2);
	}
	
	@Test
	public void TestIsValid() {
		item.SetBarcode(new Barcode("400000123455"));
		item.SetContainer(new StorageUnit("A Coffin"));
		item.SetEntry(new Date());
		item.SetProduct(new Product());
		
		assertTrue(Item.IsValid(item));
		
		//the setters force checking of all other values
	}
}
